package com.example.armmvvm.ui.customdraw.view

import android.content.Context
import android.graphics.Camera
import android.graphics.Canvas
import android.util.AttributeSet
import androidx.core.graphics.withSave

/**
 * 对复杂的canvas操作时,反向进行操作会比较简单
 *
 * @author 创建人 ：yanghaozhang
 * @version 1.0
 * @package 包名 ：com.example.armmvvm.ui.customdraw.view
 * @createTime 创建时间 ：2022/2/19
 * @modifyBy 修改人 ：
 * @modifyTime 修改时间 ：
 * @modifyMemo 修改备注：
 */
class MuchCanvasControlView @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : BaseCustomView(context, attrs, defStyleAttr) {

    // 翻页角度
    var flipRotation = 0f
        set(value) {
            field = value
            invalidate()
        }

    // 顶部Camera绕X轴角度
    var topFlip = 0f
        set(value) {
            field = value
            invalidate()
        }

    // 底部Camera绕X轴角度
    var bottomFlip = 0f
        set(value) {
            field = value
            invalidate()
        }

    /**
     * 虚拟相机
     * 坐标轴:X轴向右为正,Y轴向上为正,Z轴向屏幕内为正
     * 默认轴心为View的左上角原点
     * 相机点为原点往屏幕外的一个点
     */
    private val camera = Camera().apply {
        // 旋转
        // X轴,Z轴:左手定则为正(拇指指向正向,手指方向为正)
        // Y轴:右手定则为正

//        rotateX(50f)
//        rotateY(50f)
//        rotateZ(50f)

        // Z轴默认为-8f,屏幕外8英寸
        setLocation(0f, 0f, -8f * resources.displayMetrics.density)
    }

    /**
     * -----<对复杂的canvas操作时,反向进行操作会比较简单>----
     * 从最后一行写起,即从下往上,不用考虑canvas进行了什么操作,当canvas没有进行操作
     * 只需要考虑图形的方位坐标即可
     */
    override fun onDraw(canvas: Canvas) {

//        drawBitmap2D(canvas)

//        drawBitmap2D2(canvas)

        // 对于3D的canvas操作,正向操作将会更加复杂,反向进行操作会比较简单
        // 功能:绘制图片一角被揪起来翻页效果
        // 实现逻辑:
        //      1,绘制图片,并将图片中心移动到原点;
        //      2,将图片旋转一定角度,在X轴以下为翻页的折角;
        //      3,将折角部分通过camera绕X轴旋转一定角度,形成提起效果;
        //      4,将整个图片旋转回原来步骤2的角度;
        //      5,移动到图片需要偏移的位置
        drawBitmap3Top(canvas)
        drawBitmap3D(canvas)
    }

    private fun drawBitmap3D(canvas: Canvas) {
        canvas.withSave {
            // 5,移动到图片需要偏移的位置
            translate(offset + imageWidth / 2, offset + imageWidth / 2)
            // 4,将整个图片旋转回原来步骤2的角度;
            rotate(-flipRotation)
            // 3,将折角部分通过camera绕X轴旋转一定角度,形成提起效果;
            camera.save()
            camera.rotateX(bottomFlip)
            camera.applyToCanvas(canvas)
            camera.restore()
            // 2,将图片旋转一定角度,在X轴以下为翻页的折角;
            clipRect(-imageWidth, 0f, imageWidth, imageWidth)
            rotate(flipRotation)
            // 1,绘制图片,并将图片中心移动到原点;
            translate(-offset - imageWidth / 2, -offset - imageWidth / 2)
            drawBitmap(getAvatar(imageWidth.toInt()), offset, offset, paint)
        }
    }

    private fun drawBitmap3Top(canvas: Canvas) {
        canvas.save()
        // 5,移动到图片需要偏移的位置
        canvas.translate(offset + imageWidth / 2, offset + imageWidth / 2)
        // 4,将整个图片旋转回原来步骤2的角度;
        canvas.rotate(-flipRotation)
        // 3,将折角部分通过camera绕X轴旋转一定角度,形成提起效果;
        camera.save()
        camera.rotateX(topFlip)
        camera.applyToCanvas(canvas)
        camera.restore()
        // 2,将图片旋转一定角度,在X轴以下为翻页的折角;
        canvas.clipRect(-imageWidth, -imageWidth, imageWidth, 0f)
        canvas.rotate(flipRotation)
        // 1,绘制图片,并将图片中心移动到原点;
        canvas.translate(-offset - imageWidth / 2, -offset - imageWidth / 2)
        canvas.drawBitmap(getAvatar(imageWidth.toInt()), offset, offset, paint)
        canvas.restore()
    }

    private fun drawBitmap2D2(canvas: Canvas) {
        // 第三步:将图片偏移到(200,200)的地方
        canvas.translate(200f, 200f)
        // 第二步:图片以(imageWidth / 2f, imageWidth / 2f)为原点旋转
        canvas.rotate(45f, imageWidth / 2f, imageWidth / 2f)
        // 第一步:绘制图片
        canvas.drawBitmap(getAvatar(imageWidth.toInt()), 0f, 0f, paint)
    }

    private fun drawBitmap2D(canvas: Canvas) {
        // 第三步:图片以(200 + imageWidth / 2f, imageWidth / 2f)为原点旋转
        canvas.rotate(45f, 200 + imageWidth / 2f, imageWidth / 2f)
        // 第二步:将图片偏移到右侧200的地方
        canvas.translate(200f, 0f)
        // 第一步:绘制图片
        canvas.drawBitmap(getAvatar(imageWidth.toInt()), 0f, 0f, paint)
    }
}